import { MODEL_NAME } from '../../constants/model-names';
import { EVENTS, type IEventBus } from '../../events';
import type { BaseSnapshot } from '../../systems/save';
import { BaseModel } from '../base';

export interface CultivationV1 extends BaseSnapshot {
  version: 1;
  isCultivating: boolean;
  isAutoCultivating: boolean;
  cultivationTime: number;
  cultivatedTime: number;
  cultivationProgress: number;
}

export type CultivationSnapshot = CultivationV1;

export type CultivationSnapshotOld = CultivationV1;

export class CultivationModel extends BaseModel {
  public name = MODEL_NAME.CULTIVATION;
  private isCultivating = false;
  private isAutoCultivating = false;
  /** 修炼一次所需时间(秒) */
  private cultivationTime = 5;
  /** 已修炼时间(秒) */
  private cultivatedTime = 0;
  /** 修炼进度 */
  private cultivationProgress = 0;
  private bus: IEventBus;

  constructor(bus: IEventBus) {
    super();
    this.bus = bus;
  }

  /** 重置修炼进度 */
  private resetCultivationProgress() {
    this.cultivationProgress = 0;
  }

  /** 修炼一次 */
  public startCultivation() {
    if (this.isCultivating || this.isAutoCultivating) return;
    this.isCultivating = true;
    this.resetCultivationProgress();
    this.bus.emit(EVENTS.CULTIVATION_STATE_UPDATE);
  }

  /** 停止修炼 */
  public stopCultivation() {
    if (!this.isCultivating || this.isAutoCultivating) return;
    this.cultivatedTime = 0;
    this.isCultivating = false;
    this.resetCultivationProgress();
    this.bus.emit(EVENTS.CULTIVATION_STATE_UPDATE);
  }

  /** 自动修炼 */
  public startAutoCultivation() {
    if (this.isAutoCultivating) return;
    if (!this.isCultivating) {
      this.startCultivation();
    }
    this.isAutoCultivating = true;
    this.bus.emit(EVENTS.CULTIVATION_STATE_UPDATE);
  }

  /** 停止自动修炼 */
  public stopAutoCultivation() {
    if (!this.isAutoCultivating || this.isCultivating) return;
    this.stopCultivation();
    this.isAutoCultivating = false;
    this.bus.emit(EVENTS.CULTIVATION_STATE_UPDATE);
  }

  /** 计算修炼进度 */
  private calcCultivationProgress() {
    const cultivationTime = this.getCultivationTime();
    const currentProgress = this.cultivatedTime / cultivationTime;
    if (currentProgress >= 1) {
      this.cultivationProgress = 1;
      return;
    }
    if (currentProgress - this.cultivationProgress >= 0.01) {
      this.cultivationProgress = currentProgress;
    }
  }

  /**
   * 设置修炼时间
   * @param time 秒
   * @returns
   */
  public setCultivationTime(time: number) {
    if (time <= 0) return;
    this.cultivationTime = time;
  }

  public updateCultivationTime(dt: number) {
    if (!this.isCultivating) return;
    this.cultivatedTime += dt;
    this.calcCultivationProgress();
    const cultivationTime = this.getCultivationTime();
    if (this.cultivatedTime >= cultivationTime) {
      if (this.isAutoCultivating) {
        this.cultivatedTime -= cultivationTime;
        this.resetCultivationProgress();
      } else {
        this.stopCultivation();
      }
      this.bus.emit(EVENTS.CULTIVATION_COMPLETED);
    }
    this.bus.emit(EVENTS.CULTIVATION_STATE_UPDATE);
  }

  /** 获取是否自动修炼 */
  public getIsAutoCultivating() {
    return this.isAutoCultivating;
  }

  /** 获取修炼一次的时间(秒) */
  public getCultivationTime() {
    return this.cultivationTime;
  }

  public get uiState() {
    return {
      isCultivating: this.isCultivating,
      isAutoCultivating: this.isAutoCultivating,
      cultivationTime: this.getCultivationTime(),
      cultivatedTime: this.cultivatedTime,
      cultivationProgress: this.cultivationProgress,
    };
  }

  public save(): CultivationSnapshot {
    return {
      version: 1,
      isCultivating: this.isCultivating,
      isAutoCultivating: this.isAutoCultivating,
      cultivationTime: this.getCultivationTime(),
      cultivatedTime: this.cultivatedTime,
      cultivationProgress: this.cultivationProgress,
    };
  }

  public load(snapshot: CultivationSnapshot) {
    this.isCultivating = snapshot.isCultivating;
    this.isAutoCultivating = snapshot.isAutoCultivating;
    this.cultivationTime = snapshot.cultivationTime;
    this.cultivatedTime = snapshot.cultivatedTime;
    this.cultivationProgress = snapshot.cultivationProgress;
  }
}
